<?php
declare (strict_types=1);

namespace app\admin\controller\acl;

use app\admin\controller\CommonController;
use app\common\model\AclRole;
use ffhome\frame\model\AclPermission;
use ffhome\frame\model\AclRolePermission;
use ffhome\frame\model\AclUserRole;
use ffhome\frame\model\BaseModel;
use ffhome\frame\service\AclPermissionService;
use think\facade\Cache;
use think\facade\Db;

class Role extends CommonController
{
    protected $modelName = AclRole::MODEL_NAME;
    protected $alias = 'r';

    protected function getSearchFields(): string
    {
        $ACL_PERMISSION = AclPermission::MODEL_NAME;
        $ACL_ROLE_PERMISSION = AclRolePermission::MODEL_NAME;
        return 'r.id,r.name,r.sort,r.type,r.status,r.update_time'
            . ",(select group_concat(p.title) from {$this->prefix}{$ACL_PERMISSION} p,{$this->prefix}{$ACL_ROLE_PERMISSION} rp where p.id=rp.permission_id and rp.role_id=r.id order by p.sort) perms";
    }

    protected function getSearchDefaultSort(): array
    {
        return ['r.sort' => 'asc', 'r.id' => 'desc',];
    }

    protected function setDefaultValueInAddPage(array $row): array
    {
        $row['type'] = AclRole::T_NORMAL;
        $row['sort'] = 1000;
        return parent::setDefaultValueInAddPage($row);
    }

    protected function validateRule(array $data): array
    {
        return ['name|' . lang('role.name') => 'require'];
    }

    protected function onAfterDelete($id, array $row)
    {
        // 删除人员与角色关联
        Db::name(AclUserRole::MODEL_NAME)->whereIn('role_id', $id)->delete();
        // 删除角色权限关联
        Db::name(AclRolePermission::MODEL_NAME)->whereIn('role_id', $id)->delete();
        parent::onAfterDelete($id, $row);
    }

    protected function clearCache()
    {
        parent::clearCache();
        //清空权限相关缓存
        Cache::tag('authority')->clear();
    }

    public function authorize(int $id)
    {
        $row = $this->getModelInfo($id);
        $permList = Db::name(AclPermission::MODEL_NAME)
            ->field('id,pid,title')
            ->where('catalog', '<>', AclPermissionService::C_HOME)
            ->where('status', BaseModel::ENABLE)
            ->order('sort')
            ->select()->toJson();
        $permIds = Db::name(AclRolePermission::MODEL_NAME)->where('role_id', $id)->column('permission_id');
        $permIds = json_encode($permIds, JSON_UNESCAPED_UNICODE);
        $this->assign('row', $row);
        $this->assign('permList', $permList);
        $this->assign('permIds', $permIds);
        return $this->fetch();
    }

    public function saveAuthorize()
    {
        $roleId = $this->request->post('id');
        $node = $this->request->post('node', "[]");
        $node = json_decode($node, true);
        Db::name(AclRolePermission::MODEL_NAME)->where('role_id', $roleId)->delete();
        $data = array_map(function ($permId) use ($roleId) {
            return ['role_id' => $roleId, 'permission_id' => $permId];
        }, $node);
        Db::name(AclRolePermission::MODEL_NAME)->insertAll($data);
        $this->clearCache();
        $this->success(lang('common.save_success'));
    }
}
